#include "Listener.h"
#include "Sound.h"
#include "al.h"

namespace UniverseSound
{
	//void Listener::setListenerVolume(ALfloat vol)
	//{
	//	if (vol<0)
	//		return;
	//
	//	alListenerf(AL_GAIN, vol);
	//}

	//ALfloat Listener::getListenerVolume()
	//{
	//	ALfloat vol = 1.0;
	//	alGetListenerf(AL_GAIN, &vol);
	//	return vol;
	//}

	void Listener::setVelocity(float velx, float vely, float velz)
	{
		mVelocity.x = velx;
		mVelocity.y = vely;
		mVelocity.z = velz;
		alListener3f(AL_VELOCITY, velx, vely, velz);
	}

	void Listener::setVelocity(const Ogre::Vector3 &vel)
	{
		mVelocity = vel;
		alListener3f(AL_VELOCITY, vel.x, vel.y, vel.z);
	}

	void Listener::setPosition(ALfloat x, ALfloat y, ALfloat z)
	{
		mPosition.x = x;
		mPosition.y = y;
		mPosition.z = z;
		alListener3f(AL_POSITION, x, y, z);
	}

	void Listener::setPosition(const Ogre::Vector3 &pos)
	{
		mPosition = pos;
		alListener3f(AL_POSITION, pos.x, pos.y, pos.z);
	}

	const Ogre::Vector3& Listener::getPosition()
	{
		return mPosition;
	}

	void Listener::setOrientation(ALfloat x, ALfloat y, ALfloat z, ALfloat upx, ALfloat upy, ALfloat upz)
	{
		mOrientation[0] = x;
		mOrientation[1] = y;
		mOrientation[2] = z;
		mOrientation[3] = upx;
		mOrientation[4] = upy;
		mOrientation[5] = upz;
		alListenerfv(AL_ORIENTATION, mOrientation);
	}

	void Listener::setOrientation(const Ogre::Quaternion& q)
	{
		Ogre::Vector3 vDirection = q.zAxis();
		Ogre::Vector3 vUp = q.yAxis();

		mOrientation[0] = -vDirection.x;
		mOrientation[1] = -vDirection.y;
		mOrientation[2] = -vDirection.z;
		mOrientation[3] = vUp.x;
		mOrientation[4] = vUp.y;
		mOrientation[5] = vUp.z;

		alListenerfv(AL_ORIENTATION, mOrientation);
	}

	void Listener::update()
	{
		if (mLocalTransformDirty)
		{
			if (mParentNode)
			{
				setPosition(mParentNode->_getDerivedPosition());
				setOrientation(mParentNode->_getDerivedOrientation());
			}
			mLocalTransformDirty = false;
		}
	}

	const Ogre::String& Listener::getMovableType() const
	{
		static Ogre::String typeName = "UniverseSound: Listener";
		return typeName;
	}

	const Ogre::AxisAlignedBox& Listener::getBoundingBox() const
	{
		static Ogre::AxisAlignedBox AxisAlignedBox;
		return AxisAlignedBox;
	}

	Ogre::Real Listener::getBoundingRadius() const
	{
		return 0;
	}

	void Listener::_updateRenderQueue(Ogre::RenderQueue *rqueue)
	{
		return;
	}

	void Listener::visitRenderables(Ogre::Renderable::Visitor *visitor, bool debugRenderables)
	{
		return;
	}

	void Listener::_notifyAttached(Ogre::Node *node, bool isTagPoint)
	{
		Ogre::MovableObject::_notifyAttached(node, isTagPoint);

		// Set position and orientation if attached
		if (mParentNode)
		{
			setPosition(mParentNode->_getDerivedPosition());
			setOrientation(mParentNode->_getDerivedOrientation());
		}

		return;
	}

	void Listener::_notifyMoved()
	{
		Ogre::MovableObject::_notifyMoved();
		mLocalTransformDirty = true;
	}
}